perm filename HELP.OLD[PNT,HE] blob sn#560565 filedate 1981-02-06 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	ENTRY
C00003 00003	INTEGER #RECS,#LINKS,QUESTION_NODE,MENU_NODE,DISPLAY_NODE,PREVIOUS_DISPLAY_NODE
C00005 00004	PROCEDURE HELP_INIT
C00008 00005	PROCEDURE HELP_EXEC(INTEGER ARRAY INDEX,DATA STRING ARRAY KEYWORDS)
C00017 00006	INTERNAL PROCEDURE HELP_END
C00018 00007	INTERNAL PROCEDURE HELP(STRING KEY(NULL))
C00019 00008	END
C00020 ENDMK
C⊗;
ENTRY;
BEGIN

DEFINE $$HELP=TRUE;
REQUIRE "HEADER.SAI[pnt,he]" SOURCE_FILE;
INTEGER #RECS,#LINKS,QUESTION_NODE,MENU_NODE,DISPLAY_NODE,PREVIOUS_DISPLAY_NODE;
INTEGER CURRENT_NODE;
INTEGER ARRAY NODE_STACK[1:10];
INTEGER STACKTOP;	COMMENT CURRENT_NODE=NODE_STACK[STACKTOP];
INTEGER CHAN,BRCHAR,COUNT,EOF,FLAG;
STRING FNUM,FDAT,FKEY;
	! break tables;
INTEGER CR_BREAK,PP_BREAK,AA_BREAK,FF_BREAK,BB_BREAK,IGNORECR_BREAK;


DEFINE $HEAD "<>"=<"******************** H E L P   M O D E   ********************************">;
DEFINE $TAIL "<>"=<"*************************************************************************">;

RCLASS IREC (INTEGER ARRAY I);
RCLASS SREC (STRING ARRAY S);
RPTR(IREC) $INDEX,$DATA;
RPTR(SREC) $KEYWORDS;

STRING $HSTRING,$KSTRING,$BSTRING;	! help string,keyword stack;
INTEGER $LINE;				! top line being displayed;

BOOLEAN HELP_INITTED;
PROCEDURE HELP_INIT;
BEGIN "help_init" ! sets up the appropriate data arrays;

FNUM←"HELP.NUM[PNT,HE]";
FKEY←"HELP.KEY[PNT,HE]";
FDAT←"HELP.DAT[PNT,HE]";

OPEN(CHAN←GETCHAN,"DSK",'10,19,0,1000,BRCHAR,EOF);
LOOKUP(CHAN,FNUM,FLAG);
#RECS←WORDIN(CHAN);
#LINKS←WORDIN(CHAN);
QUESTION_NODE←WORDIN(CHAN);
MENU_NODE←WORDIN(CHAN);

	BEGIN "read in and execute"
		! data arrays ;
	STRING ARRAY KEYWORDS[1:#RECS];
	INTEGER ARRAY INDEX[1:#RECS];
	INTEGER ARRAY DATA[1:#LINKS];



	INTEGER I;
		! load up the arrays;
	ARRYIN(CHAN,INDEX[1],#RECS);
	ARRYIN(CHAN,DATA[1],#LINKS);
	RELEASE(CHAN);

	! now get the keywords;
	OPEN(CHAN←GETCHAN,"DSK",0,19,0,1000,BRCHAR,EOF);
	LOOKUP(CHAN,FKEY,FLAG);
	! initialize the break tables;
	SETBREAK(PP_BREAK←GETBREAK,"%",NULL,"INS");
	SETBREAK(CR_BREAK←GETBREAK,LF,CR,"INS");
	SETBREAK(FF_BREAK←GETBREAK,FF,NULL,"INS");
	SETBREAK(BB_BREAK←GETBREAK,"\",NULL,"INS");
	SETBREAK(AA_BREAK←GETBREAK,"∀",NULL,"INS");
	SETBREAK(IGNORECR_BREAK←GETBREAK,NULL,LF,"INS");
	INPUT(CHAN,PP_BREAK);	! get to beginning of data;
	INPUT(CHAN,CR_BREAK);	! prime it first;
	FOR I←1 STEP 1 UNTIL #RECS DO KEYWORDS[I]←INPUT(CHAN,CR_BREAK);
				! get the keywords;

	RELEASE(CHAN);
				! prepare input file for HELP MESSAGES ;
	OPEN(CHAN←GETCHAN,"DSK",0,19,0,1000,BRCHAR,EOF);
	LOOKUP(CHAN,FDAT,FLAG);

	! put the data into records so as not to lose them ;
	$INDEX←NEW_RECORD(IREC);
		MEMORY[LOCATION(IREC:I[$INDEX])]↔MEMORY[LOCATION(INDEX)];
	$DATA←NEW_RECORD(IREC);
		MEMORY[LOCATION(IREC:I[$DATA])]↔MEMORY[LOCATION(DATA)];
	$KEYWORDS←NEW_RECORD(SREC);
		MEMORY[LOCATION(SREC:S[$KEYWORDS])]↔MEMORY[LOCATION(KEYWORDS)];
	END "read in and execute";
	
HELP_INITTED←TRUE;
DISPLAY_NODE←CURRENT_NODE←QUESTION_NODE;
STACKTOP←0;
END "help_init";
PROCEDURE HELP_EXEC(INTEGER ARRAY INDEX,DATA; STRING ARRAY KEYWORDS);
BEGIN "help_exec"
SIMPLE INTEGER PROCEDURE NLINES(STRING S);
BEGIN	STRING S1; INTEGER BR;
	! counts number of lines in the string ;
	S1←S;
	S1←SCAN(S1,IGNORECR_BREAK,BR);
	RETURN(LENGTH(S)-LENGTH(S1));
END;

STRING PROCEDURE LOPLINES(REFERENCE STRING S; INTEGER N);
BEGIN	! lops off the first N lines of string S and returns it;
	STRING S1; INTEGER I,BR;
	S1←NULL;
	FOR I←1 STEP 1 UNTIL N DO
		BEGIN S1←S1&SCAN(S,CR_BREAK,BR);
		IF BR=LF THEN S1←S1&CRLF ELSE DONE;
		END;
	RETURN(S1);
END;

PROCEDURE HDISPLAY;
BEGIN	! displays a windowful;
	STRING HSTRING,DSTRING; INTEGER I;
	HSTRING←$HSTRING;
	DSTRING←LOPLINES(HSTRING,$LINE-1);
	IF HSTRING THEN DSTRING←LOPLINES(HSTRING,LASTLINE[$TTYTYPE]-9);
	FOR I←NLINES(DSTRING) STEP 1 UNTIL LASTLINE[$TTYTYPE]-11
		DO DSTRING←DSTRING&" "&CRLF;
	IF HSTRING THEN DSTRING←DSTRING&"<more can be seen by hitting formfeed>";
	OUTDPW($HEAD&CRLF&DSTRING&CRLF&$KSTRING&$BSTRING&$TAIL,
		-3,LASTLINE[$TTYTYPE]-4);
END;
	! procedure returning the appropriate help message;
STRING PROCEDURE MESSAGES(INTEGER KEY);
BEGIN	INTEGER #PG,#EL,I; STRING DAT,KEYW;
	INPUT(CHAN,PP_BREAK);	! get us to start of error messages ;
	#PG←(KEY-1) DIV 10;	! computehow many pages to move;
	#EL←KEY MOD 10;		! compute how many ∀ s to count ;
	IF #EL=0 THEN #EL←10;	! if divisible by 10 it is the last one
				  since there are 10 messages per page ;
	FOR I←1 STEP 1 UNTIL #PG DO
		DO INPUT(CHAN,FF_BREAK) UNTIL BRCHAR=FF;
				! read appropriate no of pages;
	FOR I←1 STEP 1 UNTIL #EL DO
		DO INPUT(CHAN,AA_BREAK) UNTIL BRCHAR="∀";
				! read appropriate number of ∀ ;
	INPUT(CHAN,BB_BREAK);	! this should be null;
	I←INTIN(CHAN);
	IF I≠KEY THEN PRINT("KEY =",KEY,"READ VALUE= ",I);
				! this should agree with KEY ;
	INPUT(CHAN,BB_BREAK);	! this should be null;
	KEYW←INPUT(CHAN,BB_BREAK);	! this should be the keyword;
	IF NOT EQU(KEYW,KEYWORDS[KEY])
		THEN PRINT("EXPECTED ",KEYWORDS[KEY]," GOT ",KEYW);
	DAT←NULL; DO DAT←DAT&INPUT(CHAN,BB_BREAK) UNTIL BRCHAR="\";
				! read in the error message;
	USETI(CHAN,1);		! leave us at beginning of data file ;
	RETURN(DAT);
END;


SIMPLE INTEGER PROCEDURE ANCESTOR;
	IF STACKTOP=1 THEN RETURN(CURRENT_NODE) ELSE
		RETURN(NODE_STACK[STACKTOP-1]);

PROCEDURE DISPLAY(INTEGER NODE);
	    BEGIN "printing"
	    STRING HSTRING,KSTACK,BSTRING;INTEGER BR;INTEGER TPTR,LL,UL;
	    LL←INDEX[NODE]+1;UL←INDEX[NODE+1];
	    HSTRING←NULL;
	    FOR TPTR←LL STEP 1 UNTIL UL
		DO HSTRING←HSTRING&KEYWORDS[DATA[TPTR]]
			&TAB&MESSAGES(DATA[TPTR])&CRLF;
	    KSTACK←"ANCESTORS:";
	    FOR TPTR←STACKTOP STEP -1 UNTIL 1 DO
		KSTACK←KSTACK&TAB&KEYWORDS[NODE_STACK[TPTR]];
	    $KSTRING←CVTAB(KSTACK&CRLF);
	    $HSTRING←CVTAB(HSTRING&CRLF);
	    IF CURRENT_NODE≠QUESTION_NODE THEN
	    BEGIN
	    BSTRING←"BRETHREN:";
	    TPTR←ANCESTOR;
	    LL←INDEX[TPTR]+1;UL←INDEX[TPTR+1];
	    FOR TPTR←LL STEP 1 UNTIL UL DO
		BSTRING←BSTRING&" "&KEYWORDS[DATA[TPTR]];
	    END ELSE BSTRING←NULL;
	    $BSTRING←CVTAB(BSTRING&CRLF);
	    $LINE←1;
	    HDISPLAY;
	    OUTSTR("#### ");
	    BEGIN INTEGER C;
		WHILE(C←CALL(0,"SNEAKW"))=FF OR C=VERTICAL_TAB DO
		BEGIN
		IF C=FF THEN
			$LINE←($LINE+LASTLINE[$TTYTYPE]-10) MIN
				((NLINES($HSTRING) - LASTLINE[$TTYTYPE]+13) MAX 1)
		ELSE	$LINE← ($LINE - LASTLINE[$TTYTYPE]+10) MAX 1;
		INCHRW; HDISPLAY; OUTSTR(CRLF&"#### ");
		END;
	    END;
	    PREVIOUS_DISPLAY_NODE←NODE;
	    END "printing";

INTEGER PROCEDURE CHECK_SUCCESSORS(STRING KEY; INTEGER NODE);
	BEGIN
	INTEGER I;
	FOR I←INDEX[NODE]+1 STEP 1 UNTIL INDEX[NODE+1] DO
		IF EQU(KEY,KEYWORDS[DATA[I]]) THEN RETURN(DATA[I]);
	RETURN(0);
	END;

INTEGER PROCEDURE CHECK_ANCESTORS(STRING KEY);
	BEGIN
	INTEGER I;
	FOR I←STACKTOP STEP -1 UNTIL 1 DO
		IF EQU(KEY,KEYWORDS[NODE_STACK[I]]) THEN RETURN(NODE_STACK[I]);
	RETURN(0);
	END;

PROCEDURE STACK(INTEGER NODE);
	BEGIN
	INTEGER I;
	FOR I←STACKTOP STEP -1 UNTIL 1 DO
		IF NODE=NODE_STACK[I] THEN BEGIN STACKTOP←I; RETURN END;
	NODE_STACK[STACKTOP←STACKTOP+1]←NODE;
	END;

PROCEDURE HELPER;
BEGIN	STRING KEY; INTEGER BROTHER_NODE,ANCESTOR_NODE,SUCCESSOR_NODE;
	DO BEGIN
	STACK(CURRENT_NODE);
	IF PREVIOUS_DISPLAY_NODE≠DISPLAY_NODE THEN DISPLAY (DISPLAY_NODE)
		ELSE OUTSTR("#### ");
	KEY←INCHWL;
	IF EQU(KEY,"?") THEN DISPLAY_NODE←CURRENT_NODE←QUESTION_NODE
	    ELSE IF EQU(KEY,"MENU") THEN DISPLAY_NODE←CURRENT_NODE←MENU_NODE
	    ELSE IF EQU(KEY,"UP") THEN
			DISPLAY_NODE←CURRENT_NODE←ANCESTOR
	    ELSE IF EQU(KEY,NULL) OR EQU(KEY,"DONE") THEN
			DISPLAY_NODE←CURRENT_NODE
	    ELSE IF EQU(KEY,KEYWORDS[CURRENT_NODE]) THEN
			DISPLAY_NODE←CURRENT_NODE
	    ELSE IF (SUCCESSOR_NODE←CHECK_SUCCESSORS(KEY,CURRENT_NODE)) THEN
			DISPLAY_NODE←CURRENT_NODE←SUCCESSOR_NODE
	    ELSE IF (BROTHER_NODE←CHECK_SUCCESSORS(KEY,ANCESTOR))
			THEN BEGIN DISPLAY_NODE←CURRENT_NODE←BROTHER_NODE;
				STACKTOP←STACKTOP-1 END
	    ELSE IF (ANCESTOR_NODE←CHECK_ANCESTORS(KEY))
			THEN DISPLAY_NODE←CURRENT_NODE←ANCESTOR_NODE
	    ELSE DISPLAY_NODE←QUESTION_NODE;
	END UNTIL EQU(KEY,"DONE");
END;

PREVIOUS_DISPLAY_NODE←0;	! assume nothing displayed ;
HELPER;
END "help_exec";
INTERNAL PROCEDURE HELP_END;
IF HELP_INITTED THEN
BEGIN			! release the break tables;
INTEGER I;
FOR I←IGNORECR_BREAK,PP_BREAK,CR_BREAK,AA_BREAK,FF_BREAK,BB_BREAK DO RELBREAK(I);
RELEASE(CHAN);		! release the data file channel;
$INDEX←NULL_RECORD; $DATA←NULL_RECORD; $KEYWORDS←NULL_RECORD;
HELP_INITTED←FALSE;
END;
INTERNAL PROCEDURE HELP(STRING KEY(NULL));
BEGIN
	IF NOT HELP_INITTED THEN HELP_INIT;
	IF NOT EQU(KEY,NULL) THEN
	BEGIN INTEGER I;
		FOR I←#RECS STEP -1 UNTIL 1 DO IF EQU(KEY,SREC:S[$KEYWORDS][I])
			THEN DONE;
		IF I=0 THEN BEGIN PRINT("KEYWORD "&KEY&" IS UNKNOWN"&CRLF);
			    DISPLAY_NODE←CURRENT_NODE←QUESTION_NODE;
			    END
		ELSE BEGIN DISPLAY_NODE←CURRENT_NODE←I; STACKTOP←0; END;
	END;
	HELP_EXEC(IREC:I[$INDEX],IREC:I[$DATA],SREC:S[$KEYWORDS]);
END;
END;